﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace pong1
{
    
    /// <summary>
    /// This class stores Types that are used between classes, and configuration variables loaded from file for different classes
    /// 
    /// </summary>
    public class Resources
    {
        private Resources() { }
        // Used by PongGame and PongPaddle(s) to set their sides on the screen
        public enum PADDLESIDE
        { 
            RIGHTPADDLE, LEFTPADDLE
        }

        // Used by PongGame and PongPaddle(s) tell whether they are Player1 or Player2
        public enum PLAYER
        {
            PLAYER1, PLAYER2
        }
        

        // Used by input layer and input wrapper to pass mouse button state without sending the mouse object itself
        public const int RIGHT_MOUSE_BUTTON_PRESSED = 1, LEFT_MOUSE_BUTTON_PRESSED = 2, NO_MOUSE_BUTTON_PRESSED = 3;

        // The type of game that is being played
        public enum GAMEDESCRIPTION
        {
            NONE, ONE_PLAYER_KEYBOARD, ONE_PLAYER_MOUSE, TWO_PLAYERS_KEYBOARD, SIMULATION, TWO_PLAYERS_KEYBOARD_MOUSE
        }

        private static bool gIS_FIXED_TIME_STEP = true;            // Whether to use fixed time step 
        private static bool gIS_SOUND_ON = true;                   // Whether to play sound or not 
        private static float gMAX_PADDLE_ROTATE_TIME = 1.0f;       // The amount of time a paddle will remain rotated 
        private static float gMAX_RESET_BALL_TIME = 1.5f;          // The amount of time the ball will pause in center of screen after a reset
        private static float gMIN_INPUT_TIME = 0.01f;              // The amount of time between user inputs
        private static float gPADDLE_POSITION_INCREMENT = 30;      // The number of pixels by which a paddle moves up or down when controlled by keyboard
        private static float gPADDLE_ROTATE_ANGLE = 30;            // The angle in degrees by which a paddle rotates
        private static float gBALL_VELOCITY_X = 3;                 // The x component velocity of the ball
        private static float gBALL_VELOCITY_Y = 3;                 // The y component velocity of the ball
        private static float gGAME_FRAME_RATE = 1.0f / 60.0f;               // Controls the frame rate if fixed time step is true
        private static int gMAX_VARIATION_BALL_VELOCITY = 3;             // Value used to limit variation from 0 to gMAXVARIATION_BALL_VELOCITY when randomising ball velocity 



        public static bool IS_SOUND_ON 
        {
            get { return gIS_SOUND_ON; }
            set { }
        }

        public static int  MAX_VARIATION_BALL_VELOCITY
        {
            get { return gMAX_VARIATION_BALL_VELOCITY; }
            set { }
        }

        public static float MAX_PADDLE_ROTATE_TIME
        {
            get { return gMAX_PADDLE_ROTATE_TIME; }
            set { }
        }

        public static float MAX_RESET_BALL_TIME
        {
            get { return gMAX_RESET_BALL_TIME; }
            set { }
        }

        public static float MIN_INPUT_TIME
        {
            get { return gMIN_INPUT_TIME; }
            set { }
        }

        public static float PADDLE_POSITION_INCREMENT
        {
            get { return gPADDLE_POSITION_INCREMENT; }
            set { }
        }

        public static float PADDLE_ROTATE_ANGLE
        {
            get { return gPADDLE_ROTATE_ANGLE; }
            set { }
        }

        public static float BALL_VELOCITY_X
        {
            get { return gBALL_VELOCITY_X; }
            set { }
        }

        public static float BALL_VELOCITY_Y
        {
            get { return gBALL_VELOCITY_Y; }
            set { }
        }

        public static float GAME_FRAME_RATE
        {
            get { return gGAME_FRAME_RATE; }
            set { }
        }

        public static bool IS_FIXED_TIME_STEP
        {
            get { return gIS_FIXED_TIME_STEP; }
            set { }
        }

        public const String MENU_TEXT = "[1]  Single Player Keyboard\n"
                +
                "[2]  Single Player Mouse\n"
                +
                "[3]  Two Players Keyboard\n"
                +
                "[4]  Two Players Simulation\n"
                +
                "[5]  Two Players Keyboard and Mouse\n"
                +
                "[Escape]  Press escape to exit\n";


        public static void loadValuesFromFile()
        {
            string path = @"content\pong.config"; 
            //string path = @"C:\Users\AA\Documents\temp\pong9\pong1\pong1\pong1\pong.config";
            if (!File.Exists(path))
            {
                // Set all values to default values
                gMAX_PADDLE_ROTATE_TIME = 1.0f;
                gMAX_RESET_BALL_TIME = 1.5f;
                gMIN_INPUT_TIME = 0.01f;
                gPADDLE_POSITION_INCREMENT = 30;
                gPADDLE_ROTATE_ANGLE = 30;
                gBALL_VELOCITY_X = 7;
                gBALL_VELOCITY_Y = 7;
                gGAME_FRAME_RATE = 0.016667f;
                gMAX_VARIATION_BALL_VELOCITY = 3;
                gIS_SOUND_ON = true;
            }
            else
            {
                // Open the file to read from.
                using (StreamReader sr = File.OpenText(path))
                {
                    String s = "";
                    String [] s1;
                    while((s = sr.ReadLine()) != null)
                    {
                        s1 = s.Split('=');
                        s1[0] = s1[0].Trim().ToUpper();
                        s1[1] = s1[1].Trim().ToUpper();

                        switch (s1[0])
                        {
                            case "IS_FIXED_TIME_STEP":
                                if (s1[1] == "TRUE")
                                    gIS_FIXED_TIME_STEP = true;
                                else
                                    gIS_FIXED_TIME_STEP = false;
                                break;
                            case "MAX_PADDLE_ROTATE_TIME":
                                gMAX_PADDLE_ROTATE_TIME = float.Parse(s1[1]);
                                break;
                            case "MAX_RESET_BALL_TIME":
                                gMAX_RESET_BALL_TIME = float.Parse(s1[1]);
                                break;
                            case "MIN_INPUT_TIME":
                                gMIN_INPUT_TIME = float.Parse(s1[1]);
                                break;
                            case "PADDLE_POSITION_INCREMENT ":
                                gPADDLE_POSITION_INCREMENT = float.Parse(s1[1]);
                                break;
                            case "PADDLE_ROTATE_ANGLE":
                                gPADDLE_ROTATE_ANGLE = float.Parse(s1[1]);
                                break;
                            case "BALL_VELOCITY_X":
                                gBALL_VELOCITY_X = float.Parse(s1[1]);
                                break;
                            case "BALL_VELOCITY_Y":
                                gBALL_VELOCITY_Y = float.Parse(s1[1]);
                                break;
                            case "GAME_FRAME_RATE":
                                gGAME_FRAME_RATE = float.Parse(s1[1]);
                                break;
                            case "MAX_VARIATION_BALL_VELOCITY":
                                gMAX_VARIATION_BALL_VELOCITY = int.Parse(s1[1]);
                                break;
                            case "IS_SOUND_ON":
                                if (s1[1] == "TRUE")
                                    gIS_SOUND_ON = true;
                                else
                                    gIS_SOUND_ON = false;
                                break;
                                 
                            default:
                                break;
                        }
                    }

                }

            }

        }

    }
}
